package com.bsoft.gol.hcb.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import pcn.bean.operationPlatform.request.RecipeRevokeReq;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
/**
 * @Author:FangZhiyi
 * @Description
 * @Data Created in 2020/7/31 17:24
 * @Moddified By:
 */

/**
 * 鉴权签名工具
 */
public class OperationPlatformSignUtil {
    private final static Logger log = LoggerFactory.getLogger(OperationPlatformSignUtil.class);

    private static String ip = "http://uop.bsoft.com.cn";
    //    private static String ip = "http://hcnformu.bsoft.com.cn";
    private static String publicKey = "111111";
    private static String appId = "test";
    private static String mchCode = "mch_city";

    /*药店列表*/
    public static final String PHARMACY_LIST = "/open/prescription/recipeOrder/pharmacyList";

    /*处方上传*/
    public static final String UPLOAD = "/open/prescription/recipe/upload";
    /*处方撤回*/
    public static final String REVOKE = "/open/prescription/recipe/revoke";
    /*运费查询*/
//    public static final String QUERY_FARE = "/open/prescription/drugstore/queryFare";
    public static final String QUERY_FARE = "/open/prescription/drugstore/queryShipping";
    /*订单上传*/
    public static final String SYNC_ORDER = "/open/prescription/order/syncOrder";

    /*订单取消*/
    public static final String CANCEL = "/open/prescription/order/cancel";

    /*按订单号查询物流*/
    public static final String QUERY_LOGISTICS = "/open/prescription/recipeOrder/queryLogistics/";

    /*支付方式获取*/
    public static final String PAY_CHANNEL = "/open/pay/channel";

    /*支付下单（app）*/
    public static final String PAY_CREATE = "/open/pay/create/app";

    /*支付结果查询*/
    public static final String PAY_QUERY = "/open/pay/query";

    /*支付退款*/
    public static final String PAY_REFUND = "/open/pay/refund";

    /*支付退款查询*/
    public static final String REFUND_QUERY = "/open/pay/refund/query";

    public static String sign(String publicKey, String param, String path, Map<String, String> headers) {
        StringBuilder builder = new StringBuilder();
        builder.append(path);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            builder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        //移除最后一个&
        builder.deleteCharAt(builder.length() - 1);
        if (param != null) {
            builder.append(param);
        }
        builder.append(publicKey);
        return getMD5(builder.toString(), "UTF-8");
    }

    public static String signPost(String param, String method) throws IOException {
        log.info(method + "请求处方平台入参：" + param);
        Map<String, String> headers = new TreeMap<>();
        headers.put("X-Uop-AppId", appId);
        headers.put("X-Uop-Timestamp", System.currentTimeMillis() + "");
        String signType = "";//signType
        if (!StringUtils.isEmpty(signType)) {
            headers.put("X-Uop-SignType", signType);
        }
        String crypto = "";//crypto
        if (!StringUtils.isEmpty(crypto)) {
            headers.put("X-Uop-Crypto", crypto);
        }
        String version = "";//version
        if (!StringUtils.isEmpty(version)) {
            headers.put("X-Uop-Version", version);
        }
        headers.put("X-Uop-Sign", sign(publicKey, param, method, headers));
        headers.put("X-Uop-MchCode", mchCode);
        String url = ip + method;
        String result = doPost(url, headers, param);
        log.info(method + "处方平台返回结果：" + result);
        return result;
    }

    public static String signGet(String param, String method) throws IOException {
        log.info(method + "请求处方平台入参：" + param);
        Map<String, String> headers = new TreeMap<>();
        headers.put("X-Uop-AppId", appId);
        headers.put("X-Uop-Timestamp", System.currentTimeMillis() + "");
        String signType = "";//signType
        if (!StringUtils.isEmpty(signType)) {
            headers.put("X-Uop-SignType", signType);
        }
        String crypto = "";//crypto
        if (!StringUtils.isEmpty(crypto)) {
            headers.put("X-Uop-Crypto", crypto);
        }
        String version = "";//version
        if (!StringUtils.isEmpty(version)) {
            headers.put("X-Uop-Version", version);
        }
        headers.put("X-Uop-Sign", sign(publicKey, param, method, headers));
        headers.put("X-Uop-MchCode", mchCode);
        String url = ip + method;
        String result = doGet(url, headers);
        log.info(method + "处方平台返回结果：" + result);
        return result;
    }

    public static String getMD5(String s, String charsetName) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

        try {
            byte[] btInput = s.getBytes(charsetName);
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static final String CHARSET = "UTF-8";

    public static String doPost(String apiUrl, Map<String, String> headers, String json) throws IOException {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = null;
        CloseableHttpResponse response = null;
        String result = null;
        try {
            httpPost = new HttpPost(apiUrl);
            if (null != headers && !headers.isEmpty()) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }
            StringEntity stringEntity = new StringEntity(json, CHARSET);
            stringEntity.setContentEncoding(CHARSET);
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);

            response = httpClient.execute(httpPost);
            result = EntityUtils.toString(response.getEntity(), CHARSET);
            return result;
        } finally {
            if (response != null) {
                try {
                    httpPost.releaseConnection();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String doGet(String apiUrl, Map<String, String> headers) throws IOException {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = null;
        CloseableHttpResponse response = null;
        String result = null;
        try {
            httpGet = new HttpGet(apiUrl);
            if (null != headers && !headers.isEmpty()) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.setHeader(entry.getKey(), entry.getValue());
                }
            }

            response = httpClient.execute(httpGet);
            result = EntityUtils.toString(response.getEntity(), CHARSET);
            return result;
        } finally {
            if (response != null) {
                try {
                    httpGet.releaseConnection();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
//        PharmacyListReq pharmacyListReq = new PharmacyListReq();
//        pharmacyListReq.setLatitude("30.193968911725634");
//        pharmacyListReq.setLongitude("120.1929072104893");
//        pharmacyListReq.setIsContrast(1);
//        pharmacyListReq.setHospitalIdOutter("1111111");
//        pharmacyListReq.setTypeCode("21");
//        List<DrugInfoPro> drugInfo = new ArrayList();
//        DrugInfoPro drugInfo1 = new DrugInfoPro();
//        drugInfo1.setDrugId("1627");
//        drugInfo1.setDoseUnit("85g/瓶");
//        drugInfo1.setDrugDemand("1.00");
//        drugInfo.add(drugInfo1);
//        pharmacyListReq.setDrugInfo(drugInfo);
//        String param = JSON.toJSON(pharmacyListReq).toString();

//        QueryFareReq queryFareReq = new QueryFareReq();
//        queryFareReq.setStoreId("255");
//        String[] drugIds = {"1627", "1626"};
//        queryFareReq.setDrugIds(drugIds);
//        queryFareReq.setRegionCode("350200000000");
//        String param = JSON.toJSON(queryFareReq).toString();
//        String method = QUERY_FARE;

        RecipeRevokeReq revokeReq=new RecipeRevokeReq();
        revokeReq.setRecipeIdOutter("17547784219");
        revokeReq.setOperateDt(new Date());
        String method = "/open/prescription/recipe/revoke";
        String param = JSONObject.toJSONStringWithDateFormat(revokeReq, JSON.DEFFAULT_DATE_FORMAT);

//        String method = "/open/prescription/recipeOrder/pharmacyList";


//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("orderIdOutter", "20200807000000008");
//        String param = JSONObject.toJSONStringWithDateFormat(jsonObject, JSON.DEFFAULT_DATE_FORMAT);
//        String method = "/open/prescription/recipe/revoke";
//        String method = "/open/prescription/recipeOrder/logisticsInquiry/299793462050/shunfeng";
//        String method = "/open/prescription/recipeOrder/queryLogistics/20200807000000008";
//


        String result = signPost(param, method);
        System.out.println(result);
    }

}
